/**
 * Created by liuchuanyang on 2021/9/18
 */

import { mapState, mapActions } from 'vuex';
import _            from 'lodash';
import draggable    from 'vuedraggable';
import { Draggable } from 'draggable-vue-directive'

import ELE_TYPES_Fn from './ele/ele-types';
import mutil        from '../utils/mutil';
import { PageBase } from 'jzl-web-components';

import BuilderHeader from './builder-header';
import BuilderMenu  from "./builder-menu";
import BuilderProp  from './builder-prop';
import BuilderItem  from "./builder-item";
import BuilderItemDr  from "./builder-item-dr";
import BuilderNodes from './builder-nodes';

export default {
    props: [ 'inPageId', 'appId' ],
    extends: PageBase,
    data() {
        return {
            projectId: null,
            designPageId: null,
            iAppId: null,
            loading: false,
            ready: false,
            // elems: [],
            isEditItem: false,
            currentItem: {},
            currentIndex: -1,
            currentItemElCode: '',
            hoverItemElCode: '',
            // currentEleData: {},
            pageAddShow: false,
            pageForm: {
                name: ''
            },
            activePageIndex: -1,
            items: [],
            pages: [],
            currentPage: {},

            showMainNav: false,
            commonPage: {},
            navItem: {},
            isEditNav: false,
            isMainNavPage: false,

            elemNodes: [],
            maskPos: {},
            isRouterEnter: false,
            isH5: true,
            currentItems: [],
            hoverItemCode: null,

            pinMenu: true,
            pinProp: true,

            varImpactMaps_: {},
            watchMaps_: {},
            dataset: {
                state: {},
                items: {}
            },
            // dyncComps: {},

            watchVarStop: null,
            lowcode: {
                lifecyclel: null,
                lifecycled: null,
                tablerenders: null,
                handlers: null,
                handlerx: [],
                buildret: {}
            },
            compPanelName: "选择云组件",
            compPanelShow: false,
            pageWidth: 1200
        }
    },
    directives: {
        Draggable,
    },
    components: {
        draggable,

        BuilderHeader,
        BuilderItem,
        BuilderItemDr,
        BuilderMenu,
        BuilderProp,
        BuilderNodes
    },
    async mounted () {
        // Page Base 已调用
        /*this.loading = true;
        await this.init();
        this.loading = false;*/

        this.$bus.$on("global:lowcodeChange", async (lowcode) => {
            // this.initLowcode();
            this.lowcode = lowcode;
        });
    },
    destroyed() {
        this.$bus.$off('global:lowcodeChange');
    },
    computed: {
        ...mapState([
            'loginUser',
            'project',
            'dyncComps'
        ]),
        isShowTitleProp () {
            return _.get(this.currentItem, 'tpl.header.show') === 'custom';
        },
        isCurrentFirst() {
            let itemCode = _.get(this.currentItem, 'page_item_code');
            if(!itemCode) return false;
            let index = _.findIndex(this.currentItems, { page_item_code: itemCode });

            return index === 0;
        },
        isCurrentLast() {
            let itemCode = _.get(this.currentItem, 'page_item_code');
            if(!itemCode || !this.currentItems || !this.currentItems.length) return false;
            let index = _.findIndex(this.currentItems, { page_item_code: itemCode });

            return index === (this.currentItems.length -1);
        },
        isEditPage() {
            return this.currentPage === this.currentItem;
        },
        pageTheme() {
            return _.get(this.currentPage, "style.setting.theme") || "";
        },
        pageStyle() {
            return this.$putils.getStyle(this.currentPage, "style");
        },
        /*pageType() {
            return  _.get(this.currentPage, 'type') || 2;
        }*/
    },
    watch: {
        'show': async (val, old) => {
            if(val === true) {
                this.init();
            }
        },
        inPageId(val) {
            // alert(val)
            this.init();
        },
        'currentIndex' (val, old) {

        },
        items: {
            handler(newVal, oldVal) {

                let isChange = false;

                if(newVal.length !== oldVal.length) {
                    isChange = true;
                }

                if(isChange) {
                    this.initElemNodes();

                    let diffEle = null;
                    if(newVal.length > oldVal.length) { // 新增
                        let differs = _.difference(newVal, oldVal);
                        diffEle = _.get(differs, '[0]');
                    } else {    // 删除
                        diffEle = _.get(newVal, '[0]');
                    }

                    if(diffEle) {
                        this.handleSelectItem({
                            items: this.items,
                            item: diffEle,
                            isSelectItem: true
                        });
                    }
                }
            },
            deep: true
        },
        /*'items' (val, old) {
            if(val.length > old.length) {           // 添加
                for(let i = 0; i < val.length; i++) {
                    let npicode = _.get(val, `[${i}].page_item_code`);
                    let opicode = _.get(old, `[${i}].page_item_code`);

                    if(npicode === opicode) {
                        continue;
                    }
                    this.showEdit(i);
                    break;
                    // 选中当前节点
                }
            } else if(val.length < old.length) {    // 删除
                this.currentIndex = -1;
                this.currentItem = {};
            }
        },*/
        /*'projectId' () {
            this.refresh(true);
        },*/
        '$route' (to, from){
            this.init();
        },
        'activePageIndex' (val) {
            if(val >= 0) {
                this.isMainNavPage = this._checkIsMainNavPage();
            } else {
                this.isMainNavPage = false;
            }
        },
        'currentItem.page_item_code' (val) {
            // this.initElemNodes();
            this.refreshEleNode();
            this.initDefConfig();
        },
        'currentItem': {      // 'currentItem.datas': {
            deep: true,
            handler() {
                this.updateMask()
            }
        },
        /*'currentEleData._common_style': {
            handler: function(val) {
                if(val) {
                    this.updateMask()
                }
                this.eleDataToItemData();
            },
            deep: true
        },*/
        'currentItemElCode'() {
            // this.initElemCurrentNode();
            this.updateMask()
        },
        hoverItemElCode() {
            this.updateMask()
        },
        /*'currentPage.vars': {     // 触发此处太多
            deep: true,
            handler(val) {
                console.log(`currentPage.vars is change ....`)
                console.log(JSON.stringify(val))
                this.initPageVars(this.currentPage)
            }
        }*/
    },
    beforeRouteEnter(to, from, next) {
        next(vm => {
            vm.isRouterEnter = true;
        });
    },
    methods: {
        ...mutil,
        ...mapActions([
            'setDyncComps'
        ]),
        isComp(name) {
            return this.currentItem && this.currentItem.component === name;
        },
        async init() {
            let pageId = this.$route.query.id;
            let appId = this.$route.query.appId;
            this.designPageId = this.inPageId || pageId;
            this.iAppId = this.appId || appId;

            // this.projectId = _.get(this.project, 'project_id');
            this.projectId = this.$route.query.projectId || _.get(this.project, 'project_id');

            this.reset();
            await this._refresh(true);

            await jzlJUtils.Page.loadJs(this.currentPage, jzlJUtils.PAGE_TYPE.DETAIL);

            await this.initPageVars(this.currentPage);

            this.initElemNodes();

            this.currentItems = this.items;

            await this.initLowcode();
            this.$nextTick(() => {
                this.watchLater();
                this.ready = true;
                this.$emit("ready",this.currentPage);
                this.handlePageResize();
            });
        },
        watchLater() {
            if(this.watchVarStop && typeof this.watchVarStop === 'function') this.watchVarStop();

            let watchVarStop = this.$watch('currentPage.vars', (val) => {
                this.initPageVars(this.currentPage)
            }, { deep: true });

            this.watchVarStop = watchVarStop;
        },
        async initLowcode() {
            let view_id = _.get(this.currentPage, 'page_view_id');
            let page_id = _.get(this.currentPage, 'page_id');

            if(page_id) {
                this.lowcode = await this.$japi.lowcode.getLowcodeByPage(page_id, view_id);
            }
        },
        handleItemStateChange(data) {
            let item = _.get(data, "item");
            let state = _.get(data, "state");
            let alias = _.get(item, "alias");
            let code = alias || _.get(item, "page_item_code");

            this.$set(this.dataset, `items.${ code }`, state);
            this.dataset.items[ code ] = state;
        },
        async _parse(page) {
            let pageType = _.get(this.page, 'type');
            let ELE_TYPES = ELE_TYPES_Fn();

            if(pageType === 2) {   // h5
                ELE_TYPES = ELE_TYPES_Fn('H5');
            }

            if(page && page.items) {
                for(let i = 0; i < page.items.length; i++) {
                    let it = page.items[ i ];

                    it.i = it.page_item_code;
                    // it.box_style = this.$putils.getInitMixStyle(it.box_style);
                    // it.ele_style = this.$putils.getInitMixStyle(it.ele_style);

                    if(it.is_dynccomp === 1) {
                        if(it.comp_lib && it.component) {
                            let key = `${ it.comp_lib }-${ it.component }`;

                            let compInfo = this.dyncComps[ key ];
                            let def = _.get(compInfo, "comp_def");

                            if(!def) {
                                compInfo = await this.$japi.comp.getCompByName(it.component, it.comp_lib);
                                def = _.get(compInfo, "comp_def");

                                // this.dyncComps[ key ] = def;
                                this.setDyncComps(compInfo);
                            }
                            if(def) {
                                let newItem = _.defaultsDeep(it, _.cloneDeep(def));
                                _.assignIn(it, newItem);
                            }
                        }
                    } else {    // 默认值
                        /*let component = _.get(it, "component");
                        let box_style = _.get(it, "box_style");
                        let ele_style = _.get(it, "ele_style");

                        let itemDef = _.get(ELE_TYPES, component);
                        let boxDft = _.get(itemDef, "box_style");
                        let eleDft = _.get(itemDef, "ele_style");

                        if(boxDft) {
                            it.box_style = _.defaultsDeep(box_style, boxDft);
                        }

                        if(eleDft) {
                            it.ele_style = _.defaultsDeep(ele_style, eleDft);
                        }*/

                        if(!it.subs || !_.isArray(it.subs)) it.subs = [];
                    }
                }
            }

            return page;
        },
        reset() {
            this.currentItem = {};
            this.currentIndex = -1;
            this.currentItemElCode = '';
            // this.currentEleData = {};
            this.propTab = 'style';
            this.propTabActive = 0;
            this.activePageIndex = -1;
            this.showMainNav = false;
            this.isEditNav = false;
            this.isMainNavPage = false;
            this.elemNodes = [];
            // this.maskPos = {};
        },
        async refresh() {}, // 兼容 Page Base 重复调用的问题
        async _refresh(isInit = false) {
            this.loading = true;

            let page = {};

            if(this.designPageId) {   // 修改
                page = await this.$japi.page.getPage(this.designPageId);
            } else {
                page = {
                    page_name: '页面' + this.$utils.getNanoid(6),    // this.pageForm.name,
                    // page_desc: this.pageForm.name,
                    page_code:  this.$utils.getNanoid(10),
                    project_id: this.projectId,
                    type: this.pageType || 2,
                    items: [],
                    isModify: true,
                    grid_cols: 12,
                    style: { setting: { theme: "", space: 20 }, _ss: {} }
                };
            }

            this.currentPage = await this._parse(page);
            this.items = this.currentPage.items || [];

            this.loading = false;
        },
        /*dragClone(def) {
            let comp_lib = _.get(def, "comp_lib");
            let comp_def = _.get(def, "comp_def");
            let ndef = def;

            // is_dynccomp
            if(comp_lib && comp_def) {
                ndef = _.cloneDeep(comp_def || {});
                ndef = _.defaultsDeep({
                    component: _.get(def, 'comp_name'),
                    is_dynccomp: 1,
                    comp_lib: _.get(def, 'comp_lib'),
                    icon: _.get(def, 'icon'),
                    name: _.get(def, 'name'),
                    project_id: this.projectId,
                }, ndef);
            }

            return this._dragClone(ndef, this.items);
        },*/
        addItem(item, index) {

            item.form_item_code = this.$utils.getNanoid(10);  // uuidv4().replace(/-/g, '');

            if(item.options && item.options.length) {
                for(let i = 0; i < item.options.length; i++) {
                    item.options[i].fio_code = this.$utils.getNanoid(10);     // uuidv4().replace(/-/g, '');
                }
            }

            if(index === -1) {
                this.items.unshift(item);
            } else {
                this.items.splice(index + 1, 0, item);
            }
        },
        handleSelectItem(data) {
            this.isEditItem = true;
            this.currentItem = _.get(data, 'item');
            this.currentItems = _.get(data, 'items');

            // this.currentEleData = {};
            let isSelectItem = _.get(data, 'isSelectItem');
            let targetEleName = _.get(data, "targetEleName");

            if(!targetEleName && isSelectItem) {    // 没有默认item根元素
                let itemCode = _.get(this.currentItem, "page_item_code");
                let itemNodeData = _.find(this.elemNodes, node => _.get(node, 'isRoot') && _.get(node, 'item.page_item_code') === itemCode);
                targetEleName = _.get(itemNodeData, 'code');
            }

            if(targetEleName) this.currentItemElCode = targetEleName;

            // 支持点击相同的元素，显示操作按钮
            if(this.$refs.builderNodes && this.$refs.builderNodes.showNodeActionPopover) {
                this.$refs.builderNodes.showNodeActionPopover();
            }
        },
        getIndex() {
            let itemCode = _.get(this.currentItem, 'page_item_code');
            if(!itemCode) return -1;
            return _.findIndex(this.currentItems, { page_item_code: itemCode });
        },
        moveUp() {
            let idx = this.getIndex();
            if(idx <= 0) return;
            let ci = this.currentItems.splice(idx, 1);

            this.currentItems.splice(idx -1, 0, ci[0]);
            // this.updateMask();
        },
        moveDown() {
            let idx = this.getIndex();
            if(idx < 0 || idx >= this.currentItems.length -1) return;
            let ci = this.currentItems.splice(idx, 1);

            this.currentItems.splice(idx +1, 0, ci[0]);
            // this.updateMask();
        },
        copy() {
            let idx = this.getIndex();

            if(idx < 0) return;

            let orig = this.currentItems[ idx ];
            let code = this.$utils.getNanoid(10);
            let citem = _.defaultsDeep({
                page_item_code: code,
                alias: this._getAlias(code),
                project_id: this.projectId,
                module_name: code,
                i: code
            }, orig);   // _.merge({}, this.items[index]);

            if(citem.options && citem.options.length) {
                for(let i = 0; i < citem.options.length; i++) {
                    citem.options[i].fio_code = this.$utils.getNanoid(10);
                }
            }

            this.currentItems.splice(idx + 1, 0, citem);
            this.updateMask();
            // this.$emit("selectItem", citem);
        },

        handleItemEnter(pageItemCode) {
            this.hoverItemCode = pageItemCode;
        },
        handleItemLeave(pageItemCode) {
            if(pageItemCode === this.hoverItemCode) {
                this.hoverItemCode = '';
            }
        },
        _get(obj, path) {
            return _.get(obj, path);
        },
        bindItem2Page() {
            /*if(this.activePageIndex >= 0 && this.pages[this.activePageIndex]) {
                this.pages[this.activePageIndex].items = this.items;
            }*/

            this.currentPage.items = this.items;
        },
        async submit(autoSubmit = false) {

            this.bindItem2Page();

            let projectId = _.get(this.project, 'project_id');
            let pitClone = _.cloneDeep(this.currentPage);
            let pageCode = _.get(pitClone, 'page_code');
            let regExp = new RegExp(`^[a-z][a-z\\d_]{0,19}$`, 'i');
            if(!pageCode || !regExp.test(pageCode)) {
                this.$message(`页面编码必须最多 20 位英文数字或_，且第一位必须是英文字符！`);
                return;
            }

            let idx = 1;
            let items = _.map(pitClone.items, (it) => {
                let itClone = _.cloneDeep(it);

                // 清理默认项目
                itClone.order = idx++;
                itClone.ele_style = this.clearDefaultStyle(itClone.ele_style);
                itClone.box_style = this.clearDefaultStyle(itClone.box_style);
                console.log(it.ele_style, itClone.ele_style);
                return itClone;
            });

            pitClone.project_id = projectId;
            pitClone.items = items;

            // 新增
            if(!pitClone.page_id && this.iAppId) {
                pitClone.app_id = this.iAppId;
            }

            let ret = await this.$japi.page.pageUpsert(pitClone);

            if(ret) {
                let pageId = _.get(ret, 'page_id');
                if(!autoSubmit) {
                    this.$message('操作成功！');
                    // this.back();
                }

                if(pageId && !this.designPageId) {    // 新增
                    this.designPageId = pageId;
                    this._refresh();
                }
            }
        },
        cancelSel(event) {
            /*if(event.currentTarget === event.target) {
                this.isEditItem = false;
                this.currentIndex = -1;
            }*/
        },
        _getNavItemFromCommonItems(commonItems) {

            if(!commonItems || !commonItems.length) {
                return null;
            }
            for(let i = 0; i < commonItems.length; i++) {
                let ci = commonItems[i];

                if(ci.module_type === "mainnav") {
                    return ci;
                }
            }

            return null;
        },
        _checkIsMainNavPage () {

            if(this.activePageIndex >= 0 && this.pages && this.pages.length) {
                let page = this.pages[this.activePageIndex];
                let mainNavList = _.get(this.navItem, "module_data1");

                if(page && page.page_code && mainNavList && mainNavList.length) {
                    for(let i = 0; i < mainNavList.length; i++) {
                        let it = mainNavList[i];
                        let pc = _.get(it, "link.page");

                        if (pc && pc === page.page_code) {
                            return true;
                        }
                    }
                }
            }

            return false;
        },
        handleSelectElenode(data) {
            this.currentItemElCode = _.get(data, 'code');
            this.hoverItemElCode = "";
        },
        handleHoverElenode(data) {
            this.hoverItemElCode = _.get(data, 'code') || "";
        },
        getElNodes(def, parentDef, defProp = null, parentPropPath) {
            if(!def) return null;

            let nodes = [];
            let _code = _.get(def, '_code');

            if(!_code) {
                _code = this.$utils.getNanoid(10);
                def._code = _code;
            }

            let name = _.get(def, '_name');
            let sorts = _.get(def, '_sort') || [];
            // let renderName = _.get(def, '_render');
            // if(renderName) name += `[${renderName}]`;
            let propPath = parentPropPath ? `${ parentPropPath }.${ defProp }`: defProp;

            // console.log(`---------->>>`, propPath, parentDef);
            let node = {
                code: _code,
                node: _.get(def, "_node"),
                name: name || defProp || "",
                nameEditing: false,
                propName: defProp,
                propPath: propPath,
                def: def,
                parentDef: parentDef
            };

            // 未在 sorts 里的加入
            for(let prop in def) {
                if(!_.startsWith(prop, "_") && _.indexOf(sorts, prop) < 0) {
                    sorts.push(prop);
                }
            }

            let childs = [];
            if(sorts && sorts.length) {
                for(let i = 0; i < sorts.length; i++) {
                    let prop = sorts[i];
                    let info = _.get(def, prop);

                    if(info) {
                        let snodes = this.getElNodes(info, def, prop, propPath);

                        if(snodes && snodes.length) {
                            childs = childs.concat(snodes);
                        }
                    }
                }
            }

            if(childs && childs.length) {
                node.children = childs;
            }

            nodes.push(node);

            return nodes;
        },
        // 赋值 data_schema & setting_schema
        async initDefConfig() {
            if(!this.currentItem) return;

            if(!this.currentItem.setting) this.currentItem.setting = { sticky: false };
            if(this.currentItem._isDefLoaded) {
                return;
            }

            let pageType = _.get(this.currentPage, 'type');
            let component = _.get(this.currentItem, 'component');
            let itemDef = null;

            if(this.currentItem.is_dynccomp === 1) {
                // TODO 个性化组件加载

            } else {
                let ELE_TYPES = ELE_TYPES_Fn();

                if(pageType === 2) {   // h5
                    ELE_TYPES = ELE_TYPES_Fn('H5');
                }

                itemDef = ELE_TYPES[ component ];
            }

            if(!itemDef) return;

            this.currentItem.data_schema = _.get(itemDef, 'data_schema');
            this.currentItem.setting_schema = _.get(itemDef, 'setting_schema');
            this.currentItem._isDefLoaded = true;
        },
        _getElesNodeTree(items) {
            let elemNodes = [];

            if(items && items.length) {
                let xItems = items;

                if(this.pageType == 1) {
                    xItems = _.orderBy(items, [ 'order' ], [ 'desc' ]);
                }

                for(let i = 0; i < xItems.length; i++) {
                    let item    = xItems[ i ];
                    let nodes   = this.getElNodes(item.box_style, null, "box_style");
                    let eles    = this.getElNodes(item.ele_style, null, "ele_style");
                    let root    = _.get(nodes, '[0]');
                    let rootName = _.get(item, "name") || "模块";  // `${ _.get(item, "component")}`;    // -${ _.get(root, "def._name") }

                    if(root) {
                        root.children = (root.children || []).concat(eles || []);
                    } else {
                        root = _.get(eles, '[0]');
                        nodes = eles;
                    }

                    if(root) {
                        // root.name = rootName;
                        root.alias = _.get(item, 'alias');
                        root.isRoot = true;
                        root.item = item;
                        root.items = items;
                    }

                    if(item.component === 'jzlLayout') {
                        let items = this._getElesNodeTree(item.subs);
                        root.children = items;
                    }

                    // let code = _.get(eles, '[0].code');

                    elemNodes = elemNodes.concat(nodes);

                    /*this.$nextTick(() => {
                        if(code) {
                            this.currentItemElCode = code;
                            this.$refs.nodesTree.setCurrentKey(code);
                        }
                    })*/
                }
            }

            return elemNodes;
        },
        initElemNodes(autoExpandKeys) {
            this.elemNodes = this._getElesNodeTree(this.items);
            // console.log(this.elemNodes)
        },
        refreshEleNode() {
            if(!this.currentItem) {
                this.currentItemElCode = '';
                return;
            }

            let nodes = this.getElNodes(this.currentItem.box_style, null, "box_style");
            let eles = this.getElNodes(this.currentItem.ele_style, null, "ele_style");
            let code = _.get(eles, '[0].code') || _.get(nodes, '[0].code');

            this.$nextTick(() => {
                /*if(code) {
                    this.currentItemElCode = code;
                }*/
            })
        },
        updateMask() {
            this.$nextTick(() => {
                setTimeout(()=> {
                    let $el = this.$el;
                    // let pos = { show: false };
                    // let currentItem = this.currentItem;
                    // let code = _.get(currentItem, "page_item_code");

                    let $exists = $el.querySelectorAll(`.jzl-design-ele-focus`);

                    _.each($exists, ele => {
                        this.removeClass(ele, "jzl-design-ele-focus");
                    })

                    let focusCode = this.hoverItemElCode || this.currentItemElCode;
                    if(!focusCode) return;

                    let $eles = $el.querySelectorAll(`[j-name=${ focusCode }]`);

                    _.each($eles, ele => {
                        this.addClass(ele, "jzl-design-ele-focus");
                    })

                    /*if($el && this.currentItemElCode) {
                        let eles = $el.querySelectorAll(`[name=${ this.currentItemElCode }]`);
                        pos = {
                            show: false,
                            left: 0,
                            top: 0,
                            width: 0,
                            height: 0
                        };

                        if(eles && eles.length && this.$refs.appViewBody && this.$refs.appViewBody.$el) {
                            let el = eles[0];

                            let itemPos = el.getBoundingClientRect();
                            let appPos = this.$refs.appViewBody.$el.getBoundingClientRect();
                            let left = itemPos.left - appPos.left;
                            let top = itemPos.top - appPos.top;

                            pos = {
                                show: true,
                                left: left,
                                top: top,
                                width: itemPos.width,
                                height: itemPos.height
                            }
                        }
                    }

                    this.maskPos = pos;*/
                }, 50);
            });
        },
        async handleShowCompMarket() {
            this.$WinComps({
                onSelect: (comp) => {
                    let def = _.cloneDeep(_.get(comp, 'comp_def', {}));
                    def = _.defaultsDeep({
                        component: _.get(comp, 'comp_name'),
                        is_dynccomp: 1,
                        comp_lib: _.get(comp, 'comp_lib'),
                        icon: _.get(comp, 'icon'),
                        name: _.get(comp, 'name'),
                        project_id: this.projectId,
                    }, def);

                    this.handleMarketSelectCallback(def)
                }
            });
        },
        /*handleClose() {
            if(this.isRouterEnter) {
                this.$router.back(-1)
            } else {
                this.$emit("close");
            }
        },*/
        handlePinPropChange(pinProp) {
            this.pinProp = pinProp;
        },
        handlePinMenuChange(pinMenu) {
            this.pinMenu = pinMenu;
        },
        handleChangePage(page) {

        },
        handleDropDone(info) {
            let type = _.get(info, "type");

            let isRoot = _.get(info, "draggingNode.data.isRoot");

            // 组件的移动
            if(isRoot) {
                let dragItemCode = _.get(info, "draggingNode.data.item.page_item_code");
                let dropItemCode = _.get(info, "dropNode.data.item.page_item_code");

                let dragData = this.$utils.getTreeData(this.items, "page_item_code", dragItemCode, "subs"); // _.get(draggingNode, "data");
                let dropData = this.$utils.getTreeData(this.items, "page_item_code", dropItemCode, "subs"); // _.get(draggingNode, "data");
                let dragParentData = null;
                let dropParentData = null;

                if(dragData && dragData.parent_code) {
                    dragParentData = this.$utils.getTreeData(this.items, "page_item_code", dragData.parent_code, "subs"); // _.get(draggingNode, "data");
                }

                if(dropData && dropData.parent_code) {
                    dropParentData = this.$utils.getTreeData(this.items, "page_item_code", dropData.parent_code, "subs"); // _.get(draggingNode, "data");
                }

                let dragParentChildren = [];
                let dropParentChildren = [];

                if(dragParentData && dragParentData.subs) {
                    dragParentChildren = dragParentData.subs;
                } else {
                    dragParentChildren = this.items;
                }

                if(dropParentData && dropParentData.subs) {
                    dropParentChildren = dropParentData.subs;
                } else {
                    dropParentChildren = this.items;
                }

                let dragIdx = _.findIndex(dragParentChildren, { page_item_code: dragItemCode });
                let dropIdx = _.findIndex(dropParentChildren, { page_item_code: dropItemCode });

                // console.log(`---------------->>>>>> type: ${ type }`);
                // console.log(dropData, dragData);

                if(type === "after") {

                    if(dropIdx < 0) return;

                    dragParentChildren.splice(dragIdx, 1);
                    dropParentChildren.splice(dropIdx + 1, 0, dragData);
                    dragData.parent_code = _.get(dropParentData, "page_item_code");
                } else if(type === "before") {

                    if(dropIdx < 0) return;

                    dragParentChildren.splice(dragIdx, 1);
                    dropParentChildren.splice(dropIdx, 0, dragData);
                    dragData.parent_code = _.get(dropParentData, "page_item_code");
                } else if(type === "inner") {
                    if(!dropData) return;

                    dragParentChildren.splice(dragIdx, 1);
                    if(!dropData.subs) dropData.subs = [];

                    dragData.parent_code = _.get(dropData, 'page_item_code');
                    dropData.subs.push(dragData);
                }

                // web
                if(this.pageType == 1 && dragParentChildren && dragParentChildren.length) {
                    let len = dragParentChildren.length;
                    for(let i = 0; i < dragParentChildren.length; i++) {
                        dragParentChildren[i].order = len -i;
                        console.log(len -i)
                    }
                }

                this.initElemNodes();
            } else {    // 普通元素的移动
                let dragNode = _.get(info, "draggingNode");
                let dropNode = _.get(info, "dropNode");
                // let rootNode = this.getItemRootByNode(dragNode); // 原节点获取不到了
                let rootNode = this.getItemRootByNode(dropNode);
                let item = _.get(rootNode, "data.item");
                let origPropPath = _.get(dragNode, "data.propPath");
                let origPropName = _.get(dragNode, "data.propName");
                let origInfo = _.get(item, origPropPath);
                let origContainerPath = "";
                let origContainerInfo = null;

                let distPropPath = _.get(dropNode, "data.propPath");
                let distContainerPath = distPropPath;
                let distContainerInfo = _.get(item, distContainerPath);
                let distCompareName = "";

                let origIdx = origPropPath.lastIndexOf(".");
                if(origPropPath && origIdx >= 0) {
                    origContainerPath = origPropPath.substring(0, origIdx);
                    origContainerInfo = _.get(item, origContainerPath);
                }

                if(type === "after" || type === "before") {
                    let idx = distPropPath.lastIndexOf(".");

                    distContainerPath = distPropPath.substring(0, idx);
                    distContainerInfo = _.get(item, distContainerPath);

                    distCompareName = distPropPath.substr(idx + 1);

                    if(!distCompareName) return;
                } else if(type === "inner") {

                }

                let newPropName = origPropName;

                // 命名冲突，新名字
                if(distContainerInfo[ origPropName ]) {
                    newPropName = this.$utils.getNanoid(10);
                }

                if(distContainerInfo && origContainerInfo) {
                    let distSort = _.get(distContainerInfo, "_sort");

                    if(!distSort) { // 初始化
                        distSort = [];

                        // 未在 sorts 里的加入
                        for(let prop in distContainerInfo) {
                            if(!_.startsWith(prop, "_") && _.indexOf(distSort, prop) < 0) {
                                distSort.push(prop);
                            }
                        }
                    }

                    // 增加到现有节点
                    distContainerInfo[ newPropName ] = origInfo;

                    if(distCompareName) {
                        let idx = _.indexOf(distSort, distCompareName);

                        if(idx >= 0 && _.indexOf(distSort, newPropName) < 0) {
                            distSort.splice(idx, 0, newPropName);
                        }
                    } else if(_.indexOf(distSort, newPropName) < 0) {
                        distSort.push(newPropName);
                    }

                    distContainerInfo._sort = distSort;

                    // 删除原节点
                    if(origContainerInfo) {
                        origContainerInfo[ origPropName ] = null;
                        delete origContainerInfo[ origPropName ];
                    }

                    /*if(!/^box_style/.test("box_style")) {   // box header 不 delete 不然会再次出现
                        delete origContainerInfo[ origPropName ]; // box_style.header = null ?
                    }*/

                    let origSort = _.get(origContainerInfo, "_sort");

                    if(!origSort) { // 初始化
                        origSort = [];

                        // 未在 sorts 里的加入
                        for(let prop in origContainerInfo) {
                            if(!_.startsWith(prop, "_") && _.indexOf(origSort, prop) < 0) {
                                origSort.push(prop);
                            }
                        }
                    }

                    let idx = _.indexOf(origSort, origPropName);

                    if(idx >= 0) {
                        origSort.splice(idx, 1);
                    }

                    origContainerInfo._sort = origSort;
                }

                this.initElemNodes();
            }
        },
        handleLowcodeChange(lowcode) {
           this.lowcode = lowcode;
        },
        handleMenuClick(ele) {
            let comp_lib = _.get(ele, "comp_lib");
            let comp_def = _.get(ele, "comp_def");
            let def = ele;

            // is_dynccomp
            if(comp_lib && comp_def) {
                def = _.cloneDeep(comp_def || {});
                def = _.defaultsDeep({
                    component: _.get(ele, 'comp_name'),
                    // is_dynccomp: 1,
                    comp_lib: _.get(ele, 'comp_lib'),
                    icon: _.get(ele, 'icon'),
                    name: _.get(ele, 'name'),
                    project_id: this.projectId,
                }, def);
            }

            let newEle = this._dragClone(def, this.items);
            let lastItem = null;
            let x = 0, y = 0, w = 4, h = 8, order = this.items.length;
            let ox = 0, oy = 0;

            newEle.alias = this._getAlias(newEle.code);

            _.each(this.items, it => {
                if(!it) return;

                if(it.y > oy || (it.y === oy && it.x >= ox)) {
                    lastItem = it;
                }
            });

            if(lastItem) {
                x = lastItem.x + lastItem.w;
                y = lastItem.y;

                if(x > 12 - w) {
                    x = 0;
                    y++;
                }
            }

            newEle.x = x;
            newEle.y = y;
            newEle.w = w;
            newEle.h = h;
            newEle.order = order;

            if(ele.micro) newEle.box_style = null;

            this.items.push(newEle);
            this.initElemNodes();   // 不能自动触发，手动更新，未找到原因

            this.handleSelectItem({
                items: this.items,
                item: newEle,
                isSelectItem: true
            });
            // if(nit) delete nit.name;
            // this.appendItemAfter(nit, this.currentItem);
        },
        handleShowCloudCompWin() {
            this.compPanelShow = true;
        },
        handlePageResize() {
            this.$nextTick(() => {
                let $el = _.get(this.$refs, "appViewBody.$el");
                if($el && $el.offsetWidth) {
                    this.pageWidth = $el.offsetWidth;
                }
            });
        }
    }
};
